package com.bilibili.java.books.dao.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.Date;

import org.apache.commons.codec.digest.DigestUtils;

import com.bilibili.java.books.bean.User;
import com.bilibili.java.books.dao.UserDao;
import com.bilibili.java.books.util.DateUtil;
import com.bilibili.java.books.util.JDBCUtil;
import com.bilibili.java.books.util.ParamUtil;

import net.sf.json.JSONObject;


public class UserDaoImpl implements UserDao{

	/**
	 * 账号登陆方法
	 * return 在数据库查询到的账号信息
	 */
	public User userLogin(User user) {
		Connection conn=null;
		PreparedStatement st=null;
		ResultSet rs=null;
		
		String sql="select id,account,pwd,nickname,phone from user where account=?";
		User users=null;
		try {
			//连接数据库
			conn=JDBCUtil.getConnection();
			
			st=conn.prepareStatement(sql);
			//给占位符赋值
			st.setString(1,user.getAccount());
			
			rs=st.executeQuery();
			
			
			
			if(rs.next()) {
				users=new User();
				users.setId(rs.getInt("id"));
				users.setAccount(rs.getString("account"));
				users.setPwd(rs.getString("pwd"));
				users.setNickname(rs.getString("nickname"));
				users.setPhone(rs.getString("phone"));
			}
			
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//关闭数据库
			JDBCUtil.close(conn, st, rs);
		}
		
		
		return users;
	}

	/**
	 * 手机验证码发送
	 */
	public String phoneVerify(String phone) {
		
		User user=phoneQuery(phone);
		
		if(user==null) {
			
			return "账户不存在";
			
		}
		
		
		return verifyCode(phone);
		
		
		 
	}
	
	/**
	 * 手机号查询账户是否存在
	 */
	public User phoneQuery(String phone) {
		Connection conn=null;
		String sql="select id,account,pwd,nickname,phone from user where phone=?";
		PreparedStatement ps=null;
		ResultSet rs=null;
		User user=null;
		try {
			conn=JDBCUtil.getConnection();
			 ps=conn.prepareStatement(sql);
			 
			 ps.setString(1, phone);
			 
			 rs=ps.executeQuery();
			 
			 if(rs.next()) {
				 user=new User();
				 user.setId(rs.getInt("id"));
				 user.setAccount(rs.getString("account"));
				 user.setPwd(rs.getString("pwd"));
				 user.setNickname(rs.getString("nickname"));
				 user.setPhone(rs.getString("phone"));
				
			 }
			 
			 
			 
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		return user;
		
	}
	/**
	 * 发送手机验证码的具体方法
	 * 确定需要发送的参数
	 * accountSid=a14f6bfd43ce44c9b019de57f4e2de4b&smsContent=【秒嘀科技】您的验证码是345678，30分钟输入有效。
	    &to=13896543210&timestamp=20150821100312&sig=a14f6bfd43ue44c9b019du57f4e2ee4r&respDataType=JSON
	    
	   1. accountSid,开发者主账号ID 
	   2. smsContent,短信内容        包含短信验证码和短信的内容格式 
	   3.to,手机号
	   4.timestamp,时间戳
	   5. sig,签名   ACCOUNT SID + AUTH TOKEN + timestamp使用md5进行加密
	   6.respDataType响应数据类型
	    
	    
	 */
	public String verifyCode(String phone) {
		
		//1.生成一个随机的验证码
		int code=(int)(Math.random()*(999999-100000+1))+100000;
		
		//2.封装短信内容
		String smsContent="【烽火台科技】您的验证码为"+code+"，请于10分钟内正确输入，如非本人操作，请忽略此短信。";
		
		//3.生成时间戳
		String timestamp=DateUtil.DateToString(new Date(), "yyyyMMddhhmmss");
		
		//4.生成签名
		String sig=getGin(timestamp);
		
		//5.设置返回类型
		String respDateType="JSON";
		
		//6.封装请求参数
		String param=getParam(smsContent,phone,timestamp,sig,respDateType);
		
		
		try {
			
			String reply ="{\"respCode\":\"00000\",\"respDesc\":\"请求成功。\",\"failCount\":\"0\",\"failList\":[],\"smsId\":\"3d07fbf033a64b89bb51f2f411e11159\"}";
			//String reply=sendSMS(param);
			
			//将字符串转换为JSON对象
			JSONObject json = JSONObject.fromObject(reply);
			
			//从返回的信息中获得状态码
			String resultCode = json.get("respCode").toString();
			
			//判断返回的状态吗是否是成功的状态码
			if(resultCode.equals("00000")) {
				
				if(changePhoneCode(phone,code)){
					return "短信发送成功";
				}
				return "短信发送失败。。";
				
			}
			
			return "短信发送失败";
			
		} catch (Exception e) {
			
			e.printStackTrace();
		}
		
		
		
		return "短信发送失败";
		
		
		
	}
	/**
	 * 传入验证码及到期时间
	 * @param phone
	 * @param code
	 * @return
	 */
	public boolean changePhoneCode(String phone, Integer code) {
		boolean a=false;
		Connection conn=null;
		String sql="update user set veriCode=?,deadline=date_add(now(), interval 10 minute) where phone=?";
		PreparedStatement ps=null;
		
		try {
			conn=JDBCUtil.getConnection();
			ps=conn.prepareStatement(sql);
			ps.setString(1,code+"");
			ps.setString(2, phone);
			
			int count=ps.executeUpdate();
			
			if(count!=0) {
				a=true;
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		return a;
	}

	/**
	 * 封装请求参数的方法
	 * @param smsContent
	 * @param phone
	 * @param timestamp
	 * @param sig
	 * @param respDateType
	 * @return
	 */
	public String getParam(String smsContent, String phone, String timestamp, String sig, String respDateType) {
		StringBuffer sb=new StringBuffer();
		sb.append("accountSid=").append(ParamUtil.ACCOUNT_SID).append("&smsContent=").append(smsContent)
		.append("&to=").append(phone).append("&timestamp=").append(timestamp).append("&sig=").append(sig).append("&respDataType=")
		.append(respDateType);
		return sb.toString();
		
	}

	/**
	 * 生成签名的方法
	 */
	public String getGin(String timestamp) {
		
		String ACCOUNT_SID=ParamUtil.ACCOUNT_SID;
		String AUTH_TOKEN=ParamUtil.AUTH_TOKEN;
		
		return DigestUtils.md5Hex(ACCOUNT_SID+AUTH_TOKEN+timestamp);
		
		
	}
	
	/**
	 * 真正发送短信的方法
	 * @throws IOException 
	 */
	public String sendSMS(String param) throws IOException {
		
		//1、定义一个URL请求对象
		URL url=new URL(ParamUtil.smsURL);
		
		//2.打开网络连接
		URLConnection conn=url.openConnection();
		
		//3.连接的参数设置
		conn.setConnectTimeout(2000);//超时时间
		conn.setDoInput(true);//表示是否允许向流中写入数据
		conn.setDoOutput(true);//表示是否可以获得输出的信息
		
		//4.从连接中获得输出流
		OutputStream os=conn.getOutputStream();//字节流
		//因秒滴要求格式为UTF-8，所有要将字节流转换为字符流
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));
				
		//将参数传个秒滴
		bw.write(param);
		
		//刷新流
		bw.flush();
				
		//获得秒滴的返回结果
		InputStream is= conn.getInputStream();
				
		//把节点流转换为字符流
		BufferedReader br=new BufferedReader(new InputStreamReader(is, "UTF-8"));
				
		StringBuffer sb=new StringBuffer();
		String line="";
		while((line=br.readLine())!=null) {
					
			sb.append(line);
					
		}

		br.close();
		is.close();
		os.close();
		bw.close();
				
		return sb.toString();
		
		
	}

	@Override
	public int userRegister(User user) {
		
		Connection conn = null;
		PreparedStatement ps  = null;
		int count = 0;
		try {
			conn = JDBCUtil.getConnection();

			//定于执行的SQL语句
			String sql ="insert into user(account,pwd,nickname,phone) values (?,?,?,?)";
			
			
			ps = conn.prepareStatement(sql);
			
			ps.setString(1, user.getAccount());
			ps.setString(2, user.getPwd());
			ps.setString(3, user.getNickname());
			ps.setString(4, user.getPhone());
			
			
			count = ps.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JDBCUtil.close(conn, ps, null);
		}
		
		
		return count;
		
		
	}
	
	/**
	 * 手机查询验证码方法
	 */
	public User phoneQuerya(String phone) {
		Connection conn=null;
		String sql="select id,account,pwd,nickname,phone,veriCode,deadline from user where phone=?";
		PreparedStatement ps=null;
		ResultSet rs=null;
		User user=null;
		try {
			conn=JDBCUtil.getConnection();
			 ps=conn.prepareStatement(sql);
			 
			 ps.setString(1, phone);
			 
			 rs=ps.executeQuery();
			 
			 if(rs.next()) {
				 user=new User();
				 user.setId(rs.getInt("id"));
				 user.setAccount(rs.getString("account"));
				 user.setPwd(rs.getString("pwd"));
				 user.setVeriCode(rs.getString("veriCode"));
				 user.setPhone(rs.getString("phone"));
				 String deadline=rs.getString("deadline");
				 
				 try {
					 //调用DateUtil类中的字符串日期转date对象的方法
					user.setDeadline(DateUtil.StringToDate(deadline, "yyyy-MM-dd HH:mm:ss.SSS"));
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			 }
			 
			 
			 
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
		return user;
		
	}

	
	
}
